package cloudeval.spec

import cn.edu.neu.vmmigeval.cloud.policy.MigratedHostPolicy
import cn.edu.neu.vmmigeval.cloud.policy.VmAllocation
import cn.edu.neu.vmmigeval.cloud.policy.VmPlacementPolicy
import cn.edu.neu.vmmigeval.cloud.policy.VmSelectionPolicy

/**
 * The Schedule Strategy Specification.
 *
 * @author yfwz100
 */
class VMScheduleStrategySpec {

    private Map<String, VmAllocation> strategies = new HashMap<>()

    Map<String, VmAllocation> getStrategies() {
        strategies
    }

    /**
     * The strategy specification.
     */
    private static class StrategySpec {

        private VmAllocation allocation = new VmAllocation()

        void migratedHostPolicy(MigratedHostPolicy policy) {
            allocation.migratedHost = policy
        }

        void selectionPolicy(VmSelectionPolicy policy) {
            allocation.vmSelection = policy
        }

        void placementPolicy(VmPlacementPolicy policy) {
            allocation.vmPlacement = policy
        }

    }

    /**
     * Define a strategy with given name and the delegated closure.
     *
     * @param name the name of the strategy
     * @param closure the closure to create the strategy.
     */
    void strategy(String name, @DelegatesTo(StrategySpec) Closure closure) {
        def spec = new StrategySpec()
        def code = closure.rehydrate(spec, this, this)
        code.resolveStrategy = Closure.DELEGATE_ONLY
        code()

        // add strategies into the collection.
        strategies[name] = spec.allocation
    }
}
